/**
 * 
 */
package mdb.com.vn.web.beans;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import mdb.com.vn.model.Loans;
import mdb.com.vn.services.MDBServices;
import mdb.com.vn.utils.DateUtils;
import mdb.com.vn.utils.TextUtil;
import mdb.com.vn.web.view.LoansDataModel;

/**
 * @author tu.dod
 * 
 */
@ManagedBean(name = "loansPendingBean")
@ViewScoped
public class LoansPendingBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String createdBy;
	private Date processDate;
	private Date lastUpdated;
	private Date nextProcess;

	private StreamedContent file;
	private boolean btnVisible;
	private boolean btnSaveVisible;
	private boolean btnEnableGenerate;
	private List<Date> datesUpdated;
	private List<Loans> listOfLoansPending;

	private LoansDataModel loansDataModel;
	private Loans loansSelected;
	

	@ManagedProperty("#{mdbServices}")
	private MDBServices mdbServices;

	@PostConstruct
	public void init(){
		listOfLoansPending = new ArrayList<Loans>();
		listOfLoansPending = mdbServices.getLoansByStatus(TextUtil.UNKNOWN);
		loansDataModel = new LoansDataModel(listOfLoansPending);
		lastUpdated = mdbServices.getLastUpdatedLoans(TextUtil.LOAN_MODULE);
		nextProcess = DateUtils.workingDayInfuture(lastUpdated, 14);
		
		datesUpdated = new ArrayList<Date>();
		datesUpdated = mdbServices.getDatesUpdatedLoans(TextUtil.LOAN_MODULE);
		try {
			if (DateUtils.compareDateNoTime(new Date(), nextProcess) < 0 ){
				setBtnEnableGenerate(false);
			}else{
				setBtnEnableGenerate(true);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void generateLuckyDrawForLoans() {
		if (createdBy.equals("TUNG.NS")) {
			processDate = new Date();
			Date tempDte = processDate;
			try {
				if (DateUtils.compareDateNoTime(tempDte, lastUpdated) > 0) {
					mdbServices.addLoansLuckyDrawByScript(createdBy, processDate);
					listOfLoansPending = mdbServices.getLoansByStatus(TextUtil.UNKNOWN);
					loansDataModel = new LoansDataModel(listOfLoansPending);
					FacesContext.getCurrentInstance().addMessage(
							null,
							new FacesMessage(FacesMessage.SEVERITY_INFO,
									"Đã cấp mã dự thưởng cho khách hàng", ""));
					lastUpdated = mdbServices.getLastUpdatedLoans(TextUtil.LOAN_MODULE);
					nextProcess = DateUtils.workingDayInfuture(lastUpdated, 14);
					try {
						if (DateUtils.compareDateNoTime(new Date(), nextProcess) < 0 ){
							setBtnEnableGenerate(false);
						}else{
							setBtnEnableGenerate(true);
						}
					} catch (ParseException e) {
						e.printStackTrace();
					}
				} else {
					FacesContext.getCurrentInstance().addMessage(
							null,
							new FacesMessage(FacesMessage.SEVERITY_ERROR,
									"Hệ thống đã được xử lý dữ liệu cho ngày "
											+ DateUtils.format(processDate, "dd/MM/yyyy"), ""));
				}
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} else {

			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Giao dịch bị từ chối do bạn không có quyền",
							"Vui lòng liên hệ quản trị hệ thống"));
		}

	}

	public void createExcelLoansByPoi() {
		Row row = null;
		Cell cell = null;
		try {
			Workbook wb = new HSSFWorkbook();
			HSSFCellStyle styleHeader = (HSSFCellStyle) wb.createCellStyle();
			HSSFFont fontHeader = (HSSFFont) wb.createFont();
			fontHeader.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
			styleHeader.setFont(fontHeader);
			Sheet sheet = wb.createSheet("TIEN VAY");
			row = sheet.createRow((short) 0);
			List<String> columnNames = new ArrayList<String>();

			columnNames.add("Điểm giao dịch");
			columnNames.add("Ngày tạo");
			columnNames.add("Tên khách hàng");
			columnNames.add("Số CIF");
			columnNames.add("Số hợp đồng");
			columnNames.add("Số tiền giải ngân");
			columnNames.add("Kỳ hạn (tháng)");
			columnNames.add("Lãi suất");
			columnNames.add("Loại hình vay");
			columnNames.add("Nhóm khách hàng");
			columnNames.add("Tổng số mã dự thưởng");
			for (int i = 0; i < columnNames.size(); i++) {
				cell = row.createCell(i);
				cell.setCellValue(columnNames.get(i));
				cell.setCellStyle(styleHeader);
			}
			int j = 1;
			List<Object[]> tabularData = new ArrayList<Object[]>();
			for (Loans loans : listOfLoansPending) {
				tabularData
						.add(new Object[] {
								mdbServices.getCompanyNameByCode(loans
										.getBranchCode()),
								loans.getCreatedDate(),
								loans.getCustomerName(), loans.getCustomerId(),
								loans.getRefNo(), loans.getPrAmount(),
								loans.getTerm(), loans.getInterestRate(),
								loans.getCategory(), loans.getCustomerType(),
								loans.getLkdNum() });
			}
			for (Object[] temp : tabularData) {
				row = sheet.createRow((short) j);
				HSSFCellStyle styleRow = (HSSFCellStyle) wb.createCellStyle();

				for (int k = 0; k < temp.length; k++) {
					HSSFFont fontRow = (HSSFFont) wb.createFont();
					fontRow.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
					styleRow.setFont(fontRow);
					cell = row.createCell(k);
					cell.setCellValue(temp[k].toString());
					cell.setCellStyle(styleRow);
				}
				j++;
			}
			String excelFileName = "LOANS_REPORT.xls";
			FileOutputStream fos = new FileOutputStream(excelFileName);
			wb.write(fos);
			fos.flush();
			fos.close();
			InputStream stream = new BufferedInputStream(new FileInputStream(
					excelFileName));
			file = new DefaultStreamedContent(stream, "application/xls",
					excelFileName);
			setBtnVisible(true);
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(FacesMessage.SEVERITY_INFO,
									"Xử lý xuất dữ liệu thành công",
									"Vui lòng nhấn nút 'Tải về máy' để tại file excell về máy."));
		} catch (Exception e) {
			setBtnVisible(false);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Xử lý xuất dữ liệu thất bại",
							"Vui lòng liên hệ quản trị hệ thống."));
			e.printStackTrace();
		}
	}

	public void downloadPreventedLoans() {
		file = null;
	}

	/**
	 * @return the createdBy
	 */
	public String getCreatedBy() {
		return createdBy;
	}

	/**
	 * @param createdBy
	 *            the createdBy to set
	 */
	public void setCreatedBy(String createdBy) {
		this.createdBy = createdBy;
	}

	/**
	 * @return the processDate
	 */
	public Date getProcessDate() {
		return processDate;
	}

	/**
	 * @param processDate
	 *            the processDate to set
	 */
	public void setProcessDate(Date processDate) {
		this.processDate = processDate;
	}

	/**
	 * @param mdbServices
	 *            the mdbServices to set
	 */
	public void setMdbServices(MDBServices mdbServices) {
		this.mdbServices = mdbServices;
	}

	/**
	 * @return the btnVisible
	 */
	public boolean isBtnVisible() {
		return btnVisible;
	}

	/**
	 * @param btnVisible
	 *            the btnVisible to set
	 */
	public void setBtnVisible(boolean btnVisible) {
		this.btnVisible = btnVisible;
	}

	/**
	 * @return the btnSaveVisible
	 */
	public boolean isBtnSaveVisible() {
		return btnSaveVisible;
	}

	/**
	 * @param btnSaveVisible
	 *            the btnSaveVisible to set
	 */
	public void setBtnSaveVisible(boolean btnSaveVisible) {
		this.btnSaveVisible = btnSaveVisible;
	}

	/**
	 * @return the loansSelected
	 */
	public Loans getLoansSelected() {
		return loansSelected;
	}

	/**
	 * @param loansSelected
	 *            the loansSelected to set
	 */
	public void setLoansSelected(Loans loansSelected) {
		this.loansSelected = loansSelected;
	}

	/**
	 * @return the file
	 */
	public StreamedContent getFile() {
		return file;
	}

	/**
	 * @return the loansDataModel
	 */
	public LoansDataModel getLoansDataModel() {
		return loansDataModel;
	}

	/**
	 * @return the listOfLoansPending
	 */
	public List<Loans> getListOfLoansPending() {
		return listOfLoansPending;
	}

	/**
	 * @param listOfLoansPending
	 *            the listOfLoansPending to set
	 */
	public void setListOfLoansPending(List<Loans> listOfLoansPending) {
		this.listOfLoansPending = listOfLoansPending;
	}

	/**
	 * @return the lastUpdated
	 */
	public Date getLastUpdated() {
		return lastUpdated;
	}

	/**
	 * @param lastUpdated
	 *            the lastUpdated to set
	 */
	public void setLastUpdated(Date lastUpdated) {
		this.lastUpdated = lastUpdated;
	}

	/**
	 * @return the nextProcess
	 */
	public Date getNextProcess() {
		return nextProcess;
	}

	/**
	 * @param nextProcess
	 *            the nextProcess to set
	 */
	public void setNextProcess(Date nextProcess) {
		this.nextProcess = nextProcess;
	}

	/**
	 * @return the btnEnableGenerate
	 */
	public boolean isBtnEnableGenerate() {
		return btnEnableGenerate;
	}

	/**
	 * @param btnEnableGenerate the btnEnableGenerate to set
	 */
	public void setBtnEnableGenerate(boolean btnEnableGenerate) {
		this.btnEnableGenerate = btnEnableGenerate;
	}

	/**
	 * @return the datesUpdated
	 */
	public List<Date> getDatesUpdated() {
		return datesUpdated;
	}

	/**
	 * @param datesUpdated the datesUpdated to set
	 */
	public void setDatesUpdated(List<Date> datesUpdated) {
		this.datesUpdated = datesUpdated;
	}
	

}
